package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.core.type.TypeReference;
import com.itlong.cloud.POJO.DTO.property.CloudElevatorProJsDTO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.ElevatorFloorChangeDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyDeviceCloudControllerGetDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyDeviceCloudControllerSaveDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardSyncDataPullDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.commons.dao.IPushCloudElevatorChangeLogDao;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.property.dao.IDeviceCloudControllerDao;
import com.itlong.cloud.property.dao.IDeviceElevatorFloorConfigDao;
import com.itlong.cloud.property.dao.IPropertyEquipDao;
import com.itlong.cloud.property.service.IDeviceCloudControllerService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      云群控器业务处理接口实现类
 * </desc>
 *
 * @createDate 2019/03/25
 */
@Service
@RefreshScope
public class DeviceCloudControllerServiceImpl implements IDeviceCloudControllerService{

    private static final Logger LOG = LoggerFactory.getLogger(DeviceCloudControllerServiceImpl.class);

    @Value("${" + PlatformConstants.CLOUD_CONTROLLER_TOKEN_KEY + "}")
    String cloudControllerTokenKey;

    @Autowired
    IDeviceCloudControllerDao iDeviceCloudControllerDao;

    @Autowired
    RedisService redisService;

    @Autowired
    IDeviceElevatorFloorConfigDao floorConfigDao;

    @Autowired
    private IPropertyEquipDao iPropertyEquipDao;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    private IDeviceElevatorFloorConfigDao iDeviceElevatorFloorConfigDao;

    @Autowired
    private IPushCloudElevatorChangeLogDao iPushCloudElevatorChangeLogDao;
    /**
     * <desc>
     *      检测sn是否已存在
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2019/03/25
     */
    @Override
    public Integer checkSnIsExists(String sn) {
        return iDeviceCloudControllerDao.checkSnIsExists(sn);
    }

    /**
     * <dsec>
     *      获取设备的状态
     * </dsec>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2019/03/25
     */
    @Override
    public Integer getDeviceStatus(String sn) {
        return iDeviceCloudControllerDao.getDeviceStatus(sn);
    }

    /**
     * <desc>
     *      云控制器登录
     * </desc>
     *
     * @param sn
     * @param encryptionAbility
     * @return
     * @author Jiaqi.X
     * @createDate 2019/03/25
     */
    public CloudControllerVO login(String sn,String encryptionAbility) throws Exception {
        CloudControllerVO controller = iDeviceCloudControllerDao.getDeviceInfoBySn(sn);
        if(controller!=null) {
            //设置token
            controller.setToken(UserTokenUtil.tokenEncrypt(sn, cloudControllerTokenKey, SystemTypeEnum.CLOUD_ELEVATOR_SERVER.getType()));
            //设置过期时间
            controller.setInvalidTime(DateUtil.fomatDate(
                    DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_CONTROLLER_LOGIN_TIME.intValue()),
                    "yyyy-MM-dd HH:mm:ss"
            ));
            controller.setEncryptMethod(StringUtils.isNotBlank(encryptionAbility) ? Integer.valueOf(encryptionAbility) : 0);
            //向阿里云iot中心注册设备 注册成功后更新设备信息
            if (controller.getIotDeviceId() == null) {
                Map<String, Object> params = new HashMap<>();
                params.put("deviceOperateIotType", DeviceIotEnum.REGIST_DEVICE.getCommandType());
                params.put("productKey", controller.getIotProductKey());
                params.put("deviceUnique",controller.getDeviceUnique());
                Map<String,Object> result=new HashMap<>();
                result.put("data",params);
                messageSender.send(RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_QUEUE, JsonUtil.toJSON(result),
                        RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_EXCHANGE,RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_KEY);
            }
            //设置缓存
            redisService.set(RedisConstant.CLOUD_CONTROLLER_LOGIN_REDIS_KEY + controller.getSn(),
                    RedisConstant.CLOUD_CONTROLLER_LOGIN_TIME, controller);
            //清空过期的轮询命令
            iPushCloudElevatorChangeLogDao.clearExpiredChangeLog(StringHandlerUtil.getProjectIdBySn(sn) + "5" +  StringHandlerUtil.getDeviceIdBySn(sn));
            return controller;
        }else {
            return null;
        }
    }

    /**
     * <desc>
     *      分页查询云群控器列表
     * </desc>
     *
     * @param propertyDeviceCloudControllerGetDTO 云群控器查询DTO
     * @return 分页结果
     * @author wangzhi
     * @createDate 2019/03/26
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyDeviceCloudControllerGetVO> getPage(PropertyDeviceCloudControllerGetDTO propertyDeviceCloudControllerGetDTO) throws Exception {
        if (StringUtils.isBlank(propertyDeviceCloudControllerGetDTO.getOrderColumn())) {
            //sql排序参数
            propertyDeviceCloudControllerGetDTO.setOrderColumn("dcci.create_time");
            propertyDeviceCloudControllerGetDTO.setOrderRule("DESC");
        }
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyDeviceCloudControllerGetDTO);
        Page<PropertyDeviceCloudControllerGetVO> page = new Page<>();
        page.getPage().setPageSize(propertyDeviceCloudControllerGetDTO.getPageSize());
        page.getPage().setCurrentPage(propertyDeviceCloudControllerGetDTO.getCurrentPage());
        params.put("startSlip", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        List<PropertyDeviceCloudControllerGetVO> propertyDeviceCloudControllerGetVOS = iDeviceCloudControllerDao.getPage(params);
        List<PropertyDeviceCloudControllerGetVO> propertyDeviceCloudControllerGetVOSReturn = new ArrayList<>();
        // 进行分页操作
        for (int index = page.getPage().getStartSlip(); index < page.getPage().getStartSlip() + page.getPage().getPageSize(); index++) {
            //数据条数 大于 分页起始数据下标
            if (propertyDeviceCloudControllerGetVOS.size() > index) {
                propertyDeviceCloudControllerGetVOSReturn.add(propertyDeviceCloudControllerGetVOS.get(index));
            } else {
                break;
            }
        }
        for(PropertyDeviceCloudControllerGetVO propertyDeviceCloudControllerGetVO : propertyDeviceCloudControllerGetVOSReturn) {
            propertyDeviceCloudControllerGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY + propertyDeviceCloudControllerGetVO.getDeviceUnique())) ? 1 : 0);
        }
        page.setRows(propertyDeviceCloudControllerGetVOSReturn,propertyDeviceCloudControllerGetVOS.size());
        return page;
    }

    /**
     * <desc>
     *      通过token获取用户信息
     * </desc>
     *
     * @param token
     * @return
     * @author Qiang.S
     * @createDate 2019/03/27
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public CloudControllerVO retrieve(String token) {
        try {
            if (StringUtils.isBlank(token)) {
                return null;
            }
            //解密token获取设备sn
            String sn = UserTokenUtil.tokenDecrypt(token, cloudControllerTokenKey);
            if (StringUtils.isBlank(sn)) {
                return null;
            }
            CloudControllerVO cluster = (CloudControllerVO) redisService.getObject(RedisConstant.CLOUD_CONTROLLER_LOGIN_REDIS_KEY + sn, CloudControllerVO.class);
            if (cluster == null) {
                cluster = iDeviceCloudControllerDao.getDeviceInfoBySn(sn);
                if (StringUtils.isBlank(cluster.getToken()) || !token.equals(cluster.getToken())) {
                    return null;
                }
                //重新设置缓存
                cluster.setToken(token);
                cluster.setInvalidTime(DateUtil.fomatDate(
                        DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_CONTROLLER_LOGIN_TIME.intValue()),
                        "yyyy-MM-dd HH:mm:ss"
                ));
                redisService.set(RedisConstant.CLOUD_CONTROLLER_LOGIN_REDIS_KEY + cluster.getSn(),
                        RedisConstant.CLOUD_CONTROLLER_LOGIN_TIME, cluster);
            }
            return cluster;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * <desc>
     *      查询单个云群控器
     * </desc>
     *
     * @param propertyDeviceCloudControllerGetDTO 云群控器查询DTO
     * @return 单个云群控器VO
     * @author wangzhi
     * @createDate 2019/03/27
     */
    @Override
    public PropertyDeviceCloudControllerGetVO getOne(PropertyDeviceCloudControllerGetDTO propertyDeviceCloudControllerGetDTO) throws Exception {
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyDeviceCloudControllerGetDTO);
        PropertyDeviceCloudControllerGetVO propertyDeviceCloudControllerGetVO = iDeviceCloudControllerDao.getOne(params);
        return propertyDeviceCloudControllerGetVO;
    }

    /**
     * <desc>
     *      一键启用禁用设备
     * </desc>
     *
     * @return 受影响行数
     * @author wangzhi
     * @createDate 2019/03/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer setStatus(String projectId, String deviceUnique, Integer status) throws Exception {
        List<String> deviceUniqueList = StringHandlerUtil.splitStringList(deviceUnique);
        Map<String, Object> params = new HashMap<>();
        JSONArray jsonArrayCloudController = new JSONArray();
        List<DeviceBusinessElevatorChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        for (String deviceUniqueStr : deviceUniqueList) {
            params.put("deviceId",StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUniqueStr));
            params.put("projectId",projectId);
            PropertyDeviceCloudControllerGetVO oneByDeviceId = iDeviceCloudControllerDao.getOne(params);
            // 状态发生改变，发送相关指令
            if (!status.equals(oneByDeviceId.getStatus())) {
                //向设备推送设备云电梯指令
                JSONObject jsonObjectCloudElevator = new JSONObject();
                jsonObjectCloudElevator.put("deviceUnique", deviceUnique);
                jsonObjectCloudElevator.put("projectId", projectId);
                jsonObjectCloudElevator.put("sn", oneByDeviceId.getSn());
                jsonArrayCloudController.add(jsonObjectCloudElevator);
            }
        }
        //向设备推送云群控器指令
        if (!jsonArrayCloudController.isEmpty()) {
            DeviceBusinessElevatorChangeLogPO elevatorChangeLogPO = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudController.toJSONString());
            deviceBusinessChangeLogPOS.add(elevatorChangeLogPO);
            //推送云群控器启指令
            if(!deviceBusinessChangeLogPOS.isEmpty()){
                this.pushElevator(deviceBusinessChangeLogPOS);
            }
        }
        return iDeviceCloudControllerDao.setStatus(projectId,deviceUniqueList,status);
    }

    /**
     * <desc>
     *      获取云群控器可绑定的云电梯设备列表信息
     * </desc>
     *
     * @return 电梯设备列表信息
     * @author wangzhi
     * @createDate 2019/03/27
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyDeviceCloudControllerEleVO> getCloudElevatorList(PropertyDeviceCloudControllerGetDTO propertyDeviceCloudControllerGetDTO) throws Exception {
        List<String> unitIdList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerGetDTO.getUnitId());
        // unitId进行排序连接再传参
        Collections.sort(unitIdList);
        String unitId = null;
        for (String unitIdStr : unitIdList) {
            if (StringUtils.isBlank(unitId)) {
                unitId = unitIdStr;
            } else {
                unitId = unitId + "," + unitIdStr;
            }
        }
        propertyDeviceCloudControllerGetDTO.setUnitId(unitId);
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyDeviceCloudControllerGetDTO);
        return iDeviceCloudControllerDao.getCloudElevatorList(params);
    }

    /**
     * <desc>
     *      校验所选云电梯的楼层映射表
     * </desc>
     *
     * @return 0-楼层对应表不一致，1-楼层对应表一致
     * @author wangzhi
     * @createDate 2019/03/28
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public int checkElevatorFloorConfig(String deviceUniqueElevators) throws Exception {
        List<String> deviceUniqueElevatorList = StringHandlerUtil.splitStringList(deviceUniqueElevators);
        if (deviceUniqueElevatorList.size() == 1) {
            return 1;
        }
        List<PropertyElevatorFloorConfigVO> propertyElevatorFloorConfigVOS = iDeviceCloudControllerDao.getElevatorFloorConfigGroup(deviceUniqueElevatorList);
        for (int i = 0; i < propertyElevatorFloorConfigVOS.size() - 1; i++) {
            for (int j = i + 1; j < propertyElevatorFloorConfigVOS.size(); j++) {
                if (!propertyElevatorFloorConfigVOS.get(i).equals(propertyElevatorFloorConfigVOS.get(j))) {
                    return 0;
                }
            }
        }
        return 1;
    }

    /**
     * <desc>
     *      校验所选云电梯的公共楼层是否一致
     * </desc>
     *
     * @return 0-不一致，1-一致
     * @author Juguang.S
     * @createDate 2020/06/10
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public int checkElevatorCommonFloorConfig(String deviceUniqueElevators) throws Exception {
        List<String> deviceUniqueElevatorList = StringHandlerUtil.splitStringList(deviceUniqueElevators);
        if (deviceUniqueElevatorList.size() == 1) {
            return 1;
        }
        List<String> list = iDeviceCloudControllerDao.getElevatorCommonFloorConfig(deviceUniqueElevatorList);
        for (int i = 0; i < list.size() - 1; i++) {
            for (int j = i + 1; j < list.size(); j++) {
                if (!list.get(i).equals(list.get(j))) {
                    return 0;
                }
            }
        }
        return 1;
    }

    /**
     * <desc>
     *      上报设备能力集
     * </desc>
     *
     * @param deviceUnique 设备唯一码
     * @param productKey 阿里云产品key
     * @param deviceProJs 设备属性
     * @author Qiang.S
     * @createDate 2019/03/28
     */
    @Override
    public void reportCapacitySet(String deviceUnique, String productKey, String deviceProJs) throws Exception {
        //保存设备属性
        CloudElevatorProJsDTO dto = JsonUtil.decode(deviceProJs, new TypeReference<CloudElevatorProJsDTO>() {
        });
        if(StringUtils.isEmpty(dto.getDeviceAttributes())){
            //默认型号为ITL-QK0100A
            dto.setDeviceAttributes("3");
        }
        //查询产品类型代码
        String   productCode  =  iDeviceCloudControllerDao.getProductCode(dto.getDeviceAttributes());
        dto.setProductCode(productCode);
        String  status  =  iDeviceCloudControllerDao.getCloudDeviceExist(deviceUnique);
        Map<String,Object>    daoMap  = new HashMap<>();
        daoMap.put("deviceUnique",deviceUnique);
        daoMap.put("version",dto.getVersion());
        daoMap.put("deviceAttributes",dto.getDeviceAttributes());
        daoMap.put("mac",dto.getMac());
        daoMap.put("productCode",dto.getProductCode());
        daoMap.put("cmdList",dto.getCmdList());
        if(StringUtils.isNotEmpty(status)){
            //设备存在，更新主表
            iDeviceCloudControllerDao.
                    updatePro(daoMap);
        }else{
            //更新特殊设备
            iDeviceCloudControllerDao.
                    updateSpecialPro(daoMap);
        }

        //保存上下行楼层 查询绑定电梯楼层映射表 -》 筛选楼层 -》保存
        String elevator = iDeviceCloudControllerDao.getDeviceUniqueByControllerDeviceUnique(deviceUnique);
        if(StringUtils.isNotBlank(elevator)) {
            List<DeviceElevatorFloorConfigPO> floors = iDeviceCloudControllerDao.getFloorConfigByDeviceUnique(elevator);
            StringBuilder upNaturalFloor = new StringBuilder();
            StringBuilder downNaturalFloor = new StringBuilder();
            String upFloors[] = StringHandlerUtil.splitString(dto.getUpFloor());
            String downFloors[] = StringHandlerUtil.splitString(dto.getDownFloor());
            for (DeviceElevatorFloorConfigPO floor : floors) {
                for (String up : upFloors) {
                    if (up.equals(floor.getLogicalFloor())) {
                        upNaturalFloor.append(floor.getNaturalFloor() + ",");
                        break;
                    }
                }
                for (String down : downFloors) {
                    if (down.equals(floor.getLogicalFloor())) {
                        downNaturalFloor.append(floor.getNaturalFloor() + ",");
                        break;
                    }
                }
            }
            //
            LOG.info("【群控器可控楼层信息】{} {} {} {} {} {} {}", deviceUnique, elevator, floors, dto.getUpFloor(), dto.getDownFloor(), upNaturalFloor, downNaturalFloor);
            //保存群控器可控楼层
            iDeviceCloudControllerDao.updateControllerCmdFloor(deviceUnique,
                    upNaturalFloor.length() > 0 ? upNaturalFloor.substring(0, upNaturalFloor.length() - 1) : upNaturalFloor.toString(),
                    downNaturalFloor.length() > 0 ? downNaturalFloor.substring(0, downNaturalFloor.length() - 1) : downNaturalFloor.toString());
        }

        //iot上报设备属性
//        Map<String, Object> params = new HashMap<>();
//        params.put("deviceUnique", deviceUnique);
//        params.put("productKey", productKey);
//        params.put("deviceOperateIotType", DeviceIotEnum.SAVE_DEVICE_PROP.getCommandType());
//        params.put("deviceProJs", deviceProJs);
//        Map<String, Object> result = new HashMap<>();
//        result.put("data", params);
        //向阿里云iot发送消息保存设备属性
//        messageSender.send(RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_QUEUE, JsonUtil.toJSON(params),
//                RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_EXCHANGE, RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_KEY);
    }

    /**
     * <desc>
     *      同步楼层映射表
     * </desc>
     *
     * @return 0-失败，1-成功
     * @author wangzhi
     * @createDate 2019/03/28
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer resetElevatorFloorConfig(PropertyDeviceCloudControllerSaveDTO propertyDeviceCloudControllerSaveDTO) throws Exception {
        // 先查询出楼层映射表的同步标准
        List<DeviceElevatorFloorConfigPO> deviceElevatorFloorConfigPOS = iDeviceCloudControllerDao.getElevatorFloorConfigList(propertyDeviceCloudControllerSaveDTO.getResetDeviceUnique());
        if (deviceElevatorFloorConfigPOS == null || deviceElevatorFloorConfigPOS.isEmpty()) {
            return 0;
        }
        List<String> deviceUniqueList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerSaveDTO.getDeviceUniqueElevators());
        //产品定义：云群控器关联多部电梯  如：95号梯 96号梯，选择95号，则把96号公共楼层改为和95一致；
        iDeviceCloudControllerDao.updateCommonFloorByController(propertyDeviceCloudControllerSaveDTO.getResetDeviceUnique(),deviceUniqueList);
        Date nowTime = new Date();
        List<DeviceElevatorFloorConfigPO> deviceElevatorFloorConfigPOList = new ArrayList<>();
        for (String deviceUnique : deviceUniqueList) {
            for (DeviceElevatorFloorConfigPO po : deviceElevatorFloorConfigPOS) {
                DeviceElevatorFloorConfigPO deviceElevatorFloorConfigPO = new DeviceElevatorFloorConfigPO();
                BeanUtils.copyProperties(po,deviceElevatorFloorConfigPO);
                deviceElevatorFloorConfigPO.setDeviceUnique(deviceUnique);
                deviceElevatorFloorConfigPO.setCreateTime(nowTime);
                deviceElevatorFloorConfigPO.setUpdateTime(nowTime);
                deviceElevatorFloorConfigPOList.add(deviceElevatorFloorConfigPO);
            }
        }

        // 发送相关指令，这里要旧数据，在删除之前发
        for (String deviceUnique : deviceUniqueList) {
            Map<String,Object> oldFloors = new HashMap<>();
            Map<String,Object> newFloors = new HashMap<>();
            List<DeviceElevatorFloorConfigPO> configPOList = floorConfigDao.getFloorConfigIdList(deviceUnique);
            for(DeviceElevatorFloorConfigPO configPO : configPOList){
                oldFloors.put(configPO.getNaturalFloor(),configPO.getFloorNum());
            }

            for(DeviceElevatorFloorConfigPO floorInfoDTO : deviceElevatorFloorConfigPOS){
                newFloors.put(floorInfoDTO.getFloorNum().toString(),floorInfoDTO.getNaturalFloor());
            }
            ElevatorFloorChangeDTO changeDTO = new ElevatorFloorChangeDTO();
            changeDTO.setProjectId(propertyDeviceCloudControllerSaveDTO.getProjectId());
            changeDTO.setDeviceUnique(deviceUnique);
            changeDTO.setOldFloors(oldFloors);
            changeDTO.setNewFloors(newFloors);

            Map<String, Object> map = new HashMap<>();
            map.put("elevator", changeDTO);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_QUEUE,
                    JSON.toJSONString(map),
                    RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_KEY
            );
        }
        // 先删除楼层映射表
        iDeviceCloudControllerDao.deleteElevatorFloorConfig(deviceUniqueList);
        // 再保存楼层映射表
        iDeviceCloudControllerDao.batchSaveElevatorFloorConfig(deviceElevatorFloorConfigPOList);

        for (String deviceUnique : deviceUniqueList) {
            List<DeviceElevatorFloorConfigPO> floorConfigPOList = floorConfigDao.getFloorConfigIdList(deviceUnique);
            //推送数据给一卡通
            prepareEquipInfoForSyncToSmartCard(propertyDeviceCloudControllerSaveDTO.getProjectId(), JSON.toJSONString(floorConfigPOList),2, SmartCardSyncDataOperTypeEnum.UPDATE);

            String sn  = iPropertyEquipDao.getElevatorSnByDeviceUnique(deviceUnique);
            if(StringUtils.isNotBlank(sn)) {
                List<DeviceBusinessElevatorChangeLogPO> deviceBusinessElevatorChangeLogPOs = new ArrayList<>();
                List<String> sns = new ArrayList<>();
                sns.add(sn);
                DeviceBusinessElevatorChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessElevatorChangeLogPO(StringHandlerUtil.getProjectIdBySn(sns.get(0)),
                        CloudElevatorChangeBusinessEnum.PUSH_FLOOR_INFO, JsonUtil.toJSON(sns));
                deviceBusinessElevatorChangeLogPOs.add(deviceBusinessChangeLogPO);
                this.pushElevator(deviceBusinessElevatorChangeLogPOs);
            }
        }
        return 1;
    }

    /**
     * <desc>
     *      同步公共楼层
     * </desc>
     *
     * @return 0-失败，1-成功
     * @author Juguang.S
     * @createDate 2020/06/10
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer resetElevatorCommonFloorConfig(PropertyDeviceCloudControllerSaveDTO propertyDeviceCloudControllerSaveDTO) throws Exception {

        List<String> deviceUniqueList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerSaveDTO.getDeviceUniqueElevators());
        //产品定义：云群控器关联多部电梯  如：95号梯 96号梯，选择95号，则把96号公共楼层改为和95一致；
        iDeviceCloudControllerDao.updateCommonFloorByController(propertyDeviceCloudControllerSaveDTO.getResetDeviceUnique(),deviceUniqueList);
        return 1;

    }

    /**
     * <desc>
     *      保存云群控器信息
     * </desc>
     *
     * @return 0-失败，1-成功
     * @author wangzhi
     * @createDate 2019/03/28
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer save(PropertyDeviceCloudControllerSaveDTO propertyDeviceCloudControllerSaveDTO) throws Exception {
        Date nowTime = new Date();
        // 保存云群控器信息
        DeviceCloudControllerInfoPO deviceCloudControllerInfoPO = new DeviceCloudControllerInfoPO();
        deviceCloudControllerInfoPO.setDeviceUnique(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
        deviceCloudControllerInfoPO.setDeviceId(propertyDeviceCloudControllerSaveDTO.getDeviceId());
        deviceCloudControllerInfoPO.setDeviceName(propertyDeviceCloudControllerSaveDTO.getDeviceName());
        deviceCloudControllerInfoPO.setProjectId(propertyDeviceCloudControllerSaveDTO.getProjectId());
        deviceCloudControllerInfoPO.setSn(propertyDeviceCloudControllerSaveDTO.getSn());
        deviceCloudControllerInfoPO.setDeviceMemo(propertyDeviceCloudControllerSaveDTO.getDeviceMemo());
        deviceCloudControllerInfoPO.setProductTypeId(iDeviceCloudControllerDao.getProductTypeId());
        deviceCloudControllerInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
        deviceCloudControllerInfoPO.setCreateTime(nowTime);
        deviceCloudControllerInfoPO.setUpdateTime(nowTime);
        deviceCloudControllerInfoPO.setIotProductId(iPropertyEquipDao.getIotProductId(5,propertyDeviceCloudControllerSaveDTO.getProjectId()));
        iDeviceCloudControllerDao.save(SqlUtil.durableData(deviceCloudControllerInfoPO,PlatformConstants.TABLE_SAVE));
        // 保存云群控器地址信息
        List<String> unitIdList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerSaveDTO.getUnitId());
        List<DeviceCloudControllerBridgeInfoPO> bridgeInfoPOList = new ArrayList<>();
        for (String unitId : unitIdList) {
            DeviceCloudControllerBridgeInfoPO bridgeInfoPO = new DeviceCloudControllerBridgeInfoPO();
            bridgeInfoPO.setDeviceUnique(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
            bridgeInfoPO.setBuildId(propertyDeviceCloudControllerSaveDTO.getBuildId());
            bridgeInfoPO.setUnitId(unitId);
            bridgeInfoPO.setProjectId(propertyDeviceCloudControllerSaveDTO.getProjectId());
            bridgeInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
            bridgeInfoPO.setCreateTime(nowTime);
            bridgeInfoPO.setUpdateTime(nowTime);
            bridgeInfoPOList.add(bridgeInfoPO);
        }
        iDeviceCloudControllerDao.batchSaveControllerBridge(bridgeInfoPOList);
        // 保存云群控器云电梯信息
        List<String> deviceUniqueElevatorList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerSaveDTO.getDeviceUniqueElevators());
        List<DeviceCloudControllerElevatorInfoPO> controllerElevatorInfoPOList = new ArrayList<>();
        for (String deviceUniqueElevator : deviceUniqueElevatorList) {
            DeviceCloudControllerElevatorInfoPO deviceCloudControllerElevatorInfoPO = new DeviceCloudControllerElevatorInfoPO();
            deviceCloudControllerElevatorInfoPO.setDeviceUniqueController(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
            deviceCloudControllerElevatorInfoPO.setDeviceUniqueElevator(deviceUniqueElevator);
            deviceCloudControllerElevatorInfoPO.setProjectId(propertyDeviceCloudControllerSaveDTO.getProjectId());
            deviceCloudControllerElevatorInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
            deviceCloudControllerElevatorInfoPO.setCreateTime(nowTime);
            deviceCloudControllerElevatorInfoPO.setUpdateTime(nowTime);
            controllerElevatorInfoPOList.add(deviceCloudControllerElevatorInfoPO);
        }
        iDeviceCloudControllerDao.batchSaveControllerElevator(controllerElevatorInfoPOList);

        //若添加为云电梯，同查看临时升级表是否有该条数据，若有则删除，并向电梯推送重启指令
        if(iDeviceCloudControllerDao.isExistInSpecialCloudController(deviceCloudControllerInfoPO.getDeviceUnique())>0){
            iDeviceCloudControllerDao.deleteSpecialCloudControllerByDeviceUnique(deviceCloudControllerInfoPO.getDeviceUnique());
            List<DeviceBusinessElevatorChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            JSONArray jsonArrayCloudElevator = new JSONArray();
            JSONObject jsonObjectCloudElevator = new JSONObject();
            jsonObjectCloudElevator.put("deviceUnique", deviceCloudControllerInfoPO.getDeviceUnique());
            jsonObjectCloudElevator.put("projectId", deviceCloudControllerInfoPO.getProjectId());
            jsonObjectCloudElevator.put("sn", deviceCloudControllerInfoPO.getSn());
            jsonArrayCloudElevator.add(jsonObjectCloudElevator);
            //向设备推送设备云电梯指令
            if (!jsonArrayCloudElevator.isEmpty()) {
                DeviceBusinessElevatorChangeLogPO elevatorChangeLogPO = new DeviceBusinessElevatorChangeLogPO(deviceCloudControllerInfoPO.getProjectId(), CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudElevator.toJSONString());
                deviceBusinessChangeLogPOS.add(elevatorChangeLogPO);
                //推送云电梯重启指令
                if(deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()){
                    this.pushElevator(deviceBusinessChangeLogPOS);
                }
            }
        }

        return 1;
    }

    /**
     * <desc>
     *      更新云电梯缓存iot信息
     * </desc>
     *
     * @param cloudControllerVO
     * @return
     * @author Qiang.S
     * @createDate 2019/03/28
     */
    @Override
    public CloudControllerVO updateCloudClusterIotCacheInfo(CloudControllerVO cloudControllerVO) {
        CloudControllerVO dbVo = iDeviceCloudControllerDao.getDeviceInfoBySn(cloudControllerVO.getSn());
        cloudControllerVO.setIotDeviceId(dbVo.getIotDeviceId());
        cloudControllerVO.setIotDeviceSecret(dbVo.getIotDeviceSecret());
        cloudControllerVO.setIotDeviceStatus(dbVo.getIotDeviceStatus());
        cloudControllerVO.setIotDeviceWorkStatus(dbVo.getIotDeviceWorkStatus());
        cloudControllerVO.setIotPlatform(dbVo.getIotPlatform());
        cloudControllerVO.setIotDevicePassword(dbVo.getIotDevicePassword());
        if(StringUtils.isNotBlank(cloudControllerVO.getIotDeviceId())){
            //如果iot信息不为空，则更新缓存
            cloudControllerVO.setInvalidTime(DateUtil.fomatDate(
                    DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_CONTROLLER_LOGIN_TIME.intValue()),
                    "yyyy-MM-dd HH:mm:ss"
            ));
            redisService.set(RedisConstant.CLOUD_CONTROLLER_LOGIN_REDIS_KEY + cloudControllerVO.getSn(),
                    RedisConstant.CLOUD_CONTROLLER_LOGIN_TIME, cloudControllerVO);
        }
        return cloudControllerVO;
    }

    /**
     * <desc>
     *      修改云群控器信息
     * </desc>
     *
     * @return 0-失败，1-成功
     * @author wangzhi
     * @createDate 2019/03/28
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer update(PropertyDeviceCloudControllerSaveDTO propertyDeviceCloudControllerSaveDTO) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("deviceId",StringHandlerUtil.getDeviceIdByDeviceUnique(propertyDeviceCloudControllerSaveDTO.getDeviceUnique()));
        params.put("projectId",propertyDeviceCloudControllerSaveDTO.getProjectId());
        PropertyDeviceCloudControllerGetVO oldCloudController = iDeviceCloudControllerDao.getOne(params);
        List<DeviceBusinessElevatorChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        Date nowTime = new Date();
        // 修改云群控器信息
        DeviceCloudControllerInfoPO deviceCloudControllerInfoPO = new DeviceCloudControllerInfoPO();
        deviceCloudControllerInfoPO.setDeviceUnique(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
        deviceCloudControllerInfoPO.setDeviceName(propertyDeviceCloudControllerSaveDTO.getDeviceName());
        deviceCloudControllerInfoPO.setProjectId(propertyDeviceCloudControllerSaveDTO.getProjectId());
        deviceCloudControllerInfoPO.setDeviceMemo(propertyDeviceCloudControllerSaveDTO.getDeviceMemo());
        deviceCloudControllerInfoPO.setUpdateTime(nowTime);
        iDeviceCloudControllerDao.update(SqlUtil.durableData(deviceCloudControllerInfoPO,PlatformConstants.TABLE_UPDATE));
        // 保存云群控器地址信息
        List<String> unitIdList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerSaveDTO.getUnitId());
        List<DeviceCloudControllerBridgeInfoPO> bridgeInfoPOList = new ArrayList<>();
        for (String unitId : unitIdList) {
            DeviceCloudControllerBridgeInfoPO bridgeInfoPO = new DeviceCloudControllerBridgeInfoPO();
            bridgeInfoPO.setDeviceUnique(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
            bridgeInfoPO.setBuildId(propertyDeviceCloudControllerSaveDTO.getBuildId());
            bridgeInfoPO.setUnitId(unitId);
            bridgeInfoPO.setProjectId(propertyDeviceCloudControllerSaveDTO.getProjectId());
            bridgeInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
            bridgeInfoPO.setCreateTime(nowTime);
            bridgeInfoPO.setUpdateTime(nowTime);
            bridgeInfoPOList.add(bridgeInfoPO);
        }
        // 先删除旧数据
        iDeviceCloudControllerDao.deleteControllerBridge(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
        iDeviceCloudControllerDao.batchSaveControllerBridge(bridgeInfoPOList);

        Collections.sort(unitIdList);
        String unitId = null;
        for (String unitIdStr : unitIdList) {
            if (StringUtils.isBlank(unitId)) {
                unitId = unitIdStr;
            } else {
                unitId = unitId + "," + unitIdStr;
            }
        }
        // 地址发生变化，发送指令
        if (!oldCloudController.getUnitId().equals(unitId)) {
            JSONArray jsonArrayCloudController = new JSONArray();
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("sn",oldCloudController.getSn());
            jsonObject.put("deviceUnique",oldCloudController.getDeviceUnique());
            jsonObject.put("projectId",propertyDeviceCloudControllerSaveDTO.getProjectId());
            jsonArrayCloudController.add(jsonObject);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessElevatorChangeLogPO(propertyDeviceCloudControllerSaveDTO.getProjectId(),
                    CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudController.toJSONString()));
        }

        // 设备地址没变名称发生变化，发送指令
        if (oldCloudController.getUnitId().equals(unitId) && !oldCloudController.getDeviceName().equals(propertyDeviceCloudControllerSaveDTO.getDeviceName())) {
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("sn",oldCloudController.getSn());
            jsonObject.put("deviceUnique",oldCloudController.getDeviceUnique());
            jsonObject.put("projectId",propertyDeviceCloudControllerSaveDTO.getProjectId());
            deviceBusinessChangeLogPOS.add(new DeviceBusinessElevatorChangeLogPO(propertyDeviceCloudControllerSaveDTO.getProjectId(),
                    CloudElevatorChangeBusinessEnum.PUSH_DEVICE_PROJECT,jsonObject.toJSONString()));
        }

        // 保存云群控器云电梯信息
        List<String> deviceUniqueElevatorList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerSaveDTO.getDeviceUniqueElevators());
        List<DeviceCloudControllerElevatorInfoPO> controllerElevatorInfoPOList = new ArrayList<>();
        for (String deviceUniqueElevator : deviceUniqueElevatorList) {
            DeviceCloudControllerElevatorInfoPO deviceCloudControllerElevatorInfoPO = new DeviceCloudControllerElevatorInfoPO();
            deviceCloudControllerElevatorInfoPO.setDeviceUniqueController(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
            deviceCloudControllerElevatorInfoPO.setDeviceUniqueElevator(deviceUniqueElevator);
            deviceCloudControllerElevatorInfoPO.setProjectId(propertyDeviceCloudControllerSaveDTO.getProjectId());
            deviceCloudControllerElevatorInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
            deviceCloudControllerElevatorInfoPO.setCreateTime(nowTime);
            deviceCloudControllerElevatorInfoPO.setUpdateTime(nowTime);
            controllerElevatorInfoPOList.add(deviceCloudControllerElevatorInfoPO);
        }
        // 先删除旧数据
        iDeviceCloudControllerDao.deleteControllerElevator(propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
        iDeviceCloudControllerDao.batchSaveControllerElevator(controllerElevatorInfoPOList);

        //推送云群控器指令
        if(!deviceBusinessChangeLogPOS.isEmpty()){
            this.pushElevator(deviceBusinessChangeLogPOS);
        }
        //推送项目信息群控器绑定电梯数据业务数据
        JSONObject elevatorObject = new JSONObject();
        elevatorObject.put("projectId",propertyDeviceCloudControllerSaveDTO.getProjectId());
        elevatorObject.put("deviceUnique",propertyDeviceCloudControllerSaveDTO.getDeviceUnique());
        List<DeviceBusinessElevatorChangeLogPO> changeLogPOs = new ArrayList<>();
        changeLogPOs.add(new DeviceBusinessElevatorChangeLogPO(propertyDeviceCloudControllerSaveDTO.getProjectId(), CloudElevatorChangeBusinessEnum.PUSH_PROJECT,elevatorObject.toJSONString()));
        JSONObject elevatorJs = new JSONObject();
        elevatorJs.put("data",changeLogPOs);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(elevatorJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        return 1;
    }

    /**
     * <desc>
     *       重置/修改电梯楼层映射表时，推送映射表信息给一卡通
     * <desc/>
     *
     * @param projectId        操作的所属项目ID
     * @param data             操作的电梯楼层映射表信息
     * @param operateEquipType 操作类型 添加或更新
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    public void prepareEquipInfoForSyncToSmartCard(String projectId, String data,Integer type, SmartCardSyncDataOperTypeEnum operateEquipType) throws Exception {
        //打包
        SmartCardSyncDataPullDTO smartCardSyncDataPullDTO;
        if(type == 1){
            smartCardSyncDataPullDTO = new SmartCardSyncDataPullDTO(projectId, data, operateEquipType,
                    SmartCardSyncDataTypeEnum.EQUIP_DATA);
        }else{
            smartCardSyncDataPullDTO =  new SmartCardSyncDataPullDTO(projectId, data, operateEquipType,
                    SmartCardSyncDataTypeEnum.FLOOR_RELATION_DATA);
        }

        //发送
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",JSONObject.toJSON(smartCardSyncDataPullDTO));
        messageSender.send(RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_QUEUE, JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_EXCHANGE, RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_ROUTING_KEY);
    }

    /**
     * <desc>
     *      校验云群控器和云电梯是否正在执行预约，0否，1是
     * </desc>
     *
     * @return 0否，1是
     * @author wangzhi
     * @createDate 2019/05/06
     */
    @Override
    public Integer checkCloudCallStatus(PropertyDeviceCloudControllerSaveDTO propertyDeviceCloudControllerSaveDTO) throws Exception {
        // 校验云电梯
        List<String> deviceUniqueElevatorList = StringHandlerUtil.splitStringList(propertyDeviceCloudControllerSaveDTO.getDeviceUniqueElevators());
        int countElevator = iDeviceCloudControllerDao.getCloudElevatorCallCount(deviceUniqueElevatorList);
        if (countElevator > 0) {
            return 1;
        }
        // 检验云群控器
        String deviceUniqueController = propertyDeviceCloudControllerSaveDTO.getDeviceUnique();
        if (StringUtils.isBlank(deviceUniqueController)) {
            return 0;
        }
        // 为批量处理预留
        List<String> deviceUniqueControllerList = StringHandlerUtil.splitStringList(deviceUniqueController);
        int countController = iDeviceCloudControllerDao.getCloudControllerCallCount(deviceUniqueControllerList);
        if (countController > 0) {
            return 1;
        }
        return 0;
    }

    /**
     * <desc>
     *      向设备推送设备云电梯指令
     * <desc/>
     *
     * @param   changeLogPOS     云电梯变更指令集合
     * @author Jiaqi.X
     * @createDate 2017/12/1
     */
    public void pushElevator(List<DeviceBusinessElevatorChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云电梯
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        }

    }

    /**
     * <desc>
     *      获取群控器设备详情
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/08/13
     */
    public CloudControllerFloorInfoVO getControllerFloorInfo(String deviceUnique){
        CloudControllerFloorInfoVO controller = iDeviceCloudControllerDao.getControllerFloorInfo(deviceUnique);
        if(StringUtils.isNotBlank(controller.getElevatorDeviceUnique())) {
            //获取电梯的楼层映射表
            List<DeviceElevatorFloorConfigPO> floors = iDeviceElevatorFloorConfigDao.getAroundFloors(controller.getElevatorDeviceUnique());
            List<CloudControllerFloorSubVO> subList = new ArrayList<>();
            List<String> ups = Arrays.asList(StringHandlerUtil.splitString(controller.getUpFloor()));
            List<String> downs = Arrays.asList(StringHandlerUtil.splitString(controller.getDownFloor()));
            for(DeviceElevatorFloorConfigPO floor : floors){
                CloudControllerFloorSubVO sub = new CloudControllerFloorSubVO();
                sub.setLogicFloor(floor.getLogicalFloor());
                if(ups.size() > 0){
                    if(ups.stream().filter(up->up.equals(floor.getNaturalFloor())).findFirst().isPresent()){
                        sub.setUp(1);
                    }else{
                        sub.setUp(0);
                    }
                }else{
                    sub.setUp(0);
                }
                if(downs.size()>0){
                    if(downs.stream().filter(down->down.equals(floor.getNaturalFloor())).findFirst().isPresent()){
                        sub.setDown(1);
                    }else{
                        sub.setDown(0);
                    }
                }else{
                    sub.setDown(0);
                }
                subList.add(sub);
            }
            controller.setFloorList(subList);
        }
        return controller;
    }

}
